﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Data.OleDb;
using System.Drawing;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace GreenPark
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

        IPAddress ipAddressServer;
        List<string> devIpStrs = new List<string>();
        private Socket socket = null;
        BgProcess proc = new BgProcess();

        private void cihazEkleToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frmCihaz frm = new frmCihaz();
            frm.ShowDialog(this);
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            foreach (Cihaz item in Program.Db.Cihazlar)
            {
                cmbKapi.Items.Add(item.No + "-" + item.Tanim);
            }
            txtFiltre.Focus();
            StartServer();
        }

        private string getLocalIP()
        {
            //IPHostEntry host;
            //string localIP = "";
            //host = Dns.GetHostEntry(Dns.GetHostName());
            //foreach (IPAddress ip in host.AddressList)
            //{
            //    if (ip.AddressFamily == AddressFamily.InterNetwork)
            //    {
            //        localIP = ip.ToString();
            //        break;
            //    }
            //}
            //return localIP;

            return ConfigurationManager.AppSettings["ServerIP"].ToString();

        }

        private bool AddIP2List(string ip)
        {
            if (!IsIPCorrect(ip))
            {
                return false;
            }
            else
            {
                devIpStrs.Add(ip);
                return true;
            }
        }

        private bool IsIPCorrect(string ipStr)
        {
            IPAddress ipAddress;
            if (IPAddress.TryParse(ipStr, out ipAddress))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private void StartServer()
        {
            string ipadres = getLocalIP();
            if (!IPAddress.TryParse(ipadres, out ipAddressServer))
            {
                MessageBox.Show("Sunucu IP Adresi geçersiz !");
                return;
            }

            foreach (Cihaz item in Program.Db.Cihazlar)
            {
                if (!AddIP2List(item.IpAdresi))
                {
                    MessageBox.Show(item.No + " No lu cihaza girdiğiniz ip adresi geçersiz !");
                }
            }

            if (devIpStrs.Count == 0)
            {
                return;
            }

            Thread thread = new Thread(new ThreadStart(Monitor));
            thread.Start();
        }

        bool quitMonitor = false;
        private void Monitor()
        {
            Cihaz deviceInfo = new Cihaz();

            IPEndPoint iep = new IPEndPoint(ipAddressServer, 9923);

            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                socket.Bind(iep);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Fail to bind with the Server IP address, please set it again.");
                return;
            }
            socket.Listen(15);

            // do c# 结束线程 (Process finished)
            while (!quitMonitor)
            {
                try
                {
                    Socket newSocket = socket.Accept();
                    ThreadPool.QueueUserWorkItem(new WaitCallback(ReceiveSocketData), newSocket);
                }
                catch (SocketException ex)
                {
                }
            }
        }


        private string GetDeviceInfo(String ipStr)
        {
            string devInfo;

            devInfo = "DeviceInfo( dev_id = \"1\" dev_type = \"HW_HDCP\" comm_type = \"ip\" ip_address = \"" + ipStr + "\")";
            return devInfo;

        }


        CallBack myCallBack;
        int BeCalled(ulong nTotal, ulong nDone)
        {
            return 0;
        }

        private void openDoor(String ipStr)
        {
            string devInfo, cmdStr, retStr;
            retStr = "";
            IntPtr ret = IntPtr.Zero;
            uint retlen = 0;
            devInfo = GetDeviceInfo(ipStr);
            cmdStr = "OpenDoor()";
            myCallBack = new CallBack(BeCalled);
            int result;
            result = Process.HwDev_Execute(devInfo, devInfo.Length, cmdStr, cmdStr.Length, ref retStr, ref retlen, BeCalled);

            if (result == 0)
            {
            }
            else
            {

            }
        }



        private void ReceiveSocketData(object newSocket)
        {
            Socket curSocket = (Socket)(newSocket);
            string strTmp = null;
            string strOneRecord = null;
            string strKind = "";

            int recordBegin = 0;
            int recordEnd = 0;
            int rcfLength = 0;
            byte[] byteMessage = new byte[4096];
            try
            {
                do
                {
                    rcfLength = curSocket.Receive(byteMessage);

                    Encoding gb = Encoding.GetEncoding("gb2312");
                    strTmp += gb.GetString(byteMessage, 0, rcfLength);
                    // strTmp += Encoding.get.GetString(byteMessage, 0, rcfLength);
                    recordBegin = strTmp.IndexOf("(");
                    if (recordBegin >= 0)
                    {
                        recordEnd = strTmp.IndexOf(")", recordBegin);
                    }

                    if (recordBegin > 0 && recordEnd > 0)
                    {
                        strOneRecord = strTmp.Substring(recordBegin + 1, recordEnd - recordBegin - 1);
                        strTmp = strTmp.Substring(recordEnd + 1);

                        List<RecordInfo> riList = Hanvon.KMS.Utils.HWParser.ParseToRcdInfoList("0", strOneRecord, null);
                        if (riList == null || riList.Count == 0)
                        {
                            continue;
                        }

                        foreach (RecordInfo ri in riList)
                        {
                            string ipStr = ((IPEndPoint)curSocket.RemoteEndPoint).Address.ToString();
                            if (!devIpStrs.Contains(ipStr))
                            {
                                continue;
                            }

                            if (!string.IsNullOrEmpty(ri.EmployeeCode))
                            {
                                if (proc.CheckContract(ri.EmployeeCode))
                                {
                                    this.pictureBox1.Image = (Image)Image.FromStream(new System.IO.MemoryStream(ri.ImageData));
                                    proc.InsertActivity(Convert.ToInt32(ri.EmployeeCode.Trim()), ipStr);
                                    openDoor(ipStr);
                                }
                            }


                        }
                    }
                } while (rcfLength > 0);
            }
            catch (SocketException ex)
            {
                // this.label1.Text += ex.ToString();
            }

        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            //lstCihazlar.Items.Clear();
            if (!backgroundWorker1.IsBusy)
            {
                backgroundWorker1.RunWorkerAsync();
            }


        }

        delegate void SetTextCallback(string text);
        delegate void AddItemCallback(string text);
        delegate void SetErrorTextCallback(string text);


        private void SetText(string text)
        {
            if (this.txtAktarim.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetText);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.txtAktarim.Text = text;
            }
        }

        private void SetErrorText(string text)
        {
            if (this.txtAktarim.InvokeRequired)
            {
                SetErrorTextCallback d = new SetErrorTextCallback(SetErrorText);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.txtAktarim.Tag = text;
            }
        }

        private void AddItem(string text)
        {
            //if (this.lstCihazlar.InvokeRequired)
            //{
            //    AddItemCallback d = new AddItemCallback(AddItem);
            //    this.Invoke(d, new object[] { text });
            //}
            //else
            //{
            //    this.lstCihazlar.Items.Add(text);
            //}
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            //SetText("Aktarım Durumu: Aktarıma başlandı !");
            //if (File.Exists(Application.StartupPath + "\\log.txt"))
            //{
            //    File.Delete(Application.StartupPath + "\\log.txt");
            //}

            //foreach (Cihaz item in Program.Db.Cihazlar)
            //{
            //    if (Process.DeviceExists(item.IpAdresi))
            //    {
            //        AddItem(item.Tanim);
            //    }
            //}

            //try
            //{
            //    if (Program.Db.Cihazlar.Count > 0)
            //    {
            //        BgProcess pr = new BgProcess();
            //        pr.ImportDb();
            //        foreach (Users item in Program.Db.Uyeler)
            //        {
            //            if (item.Chz1 == KayitDurumu.Eklenecek || item.Chz2 == KayitDurumu.Eklenecek || item.Chz3 == KayitDurumu.Eklenecek || item.Chz4 == KayitDurumu.Eklenecek)
            //            {
            //                Process.AddCustomer(item);
            //            }
            //            else if (item.Chz1 == KayitDurumu.Silinecek || item.Chz2 == KayitDurumu.Silinecek || item.Chz3 == KayitDurumu.Silinecek || item.Chz4 == KayitDurumu.Silinecek)
            //            {
            //                Process.DeleteCustomer(item);
            //            }

            //        }
            //        SetText("Aktarım Durumu: Aktarım tamamlandı !");
            //    }
            //    else
            //    {
            //        SetText("Tanımlı Cihaz Bulunamadı  !");
            //    }

            //}
            //catch (Exception ex)
            //{
            //    SetText("Aktarım Durumu: Sunucu ile bağlantı kurulamadı !");
            //    SetErrorText(ex.Message + "\r\n" + ex.StackTrace);
            //}
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://www.bilisimbarkod.com");
        }

        private void txtAktarim_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            if (txtAktarim.Tag != null)
            {
                MessageBox.Show(txtAktarim.Tag.ToString());
            }
        }

        private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            quitMonitor = true;
            File.WriteAllText(Application.StartupPath + "\\ayarlar.txt", JsonConvert.SerializeObject(Program.Db));
            System.Environment.Exit(System.Environment.ExitCode);
        }

        private void btnAra_Click(object sender, EventArgs e)
        {
            dataGridView1.DataSource = proc.EmployeFind(txtFiltre.Text);
            dataGridView1.AutoResizeColumns();
        }

        private void txtFiltre_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                if (!string.IsNullOrEmpty(txtFiltre.Text))
                    dataGridView1.DataSource = proc.EmployeFind(txtFiltre.Text);

                dataGridView1.AutoResizeColumns();
            }
        }

        private void btnMasterCopy_Click(object sender, EventArgs e)
        {
            if (dataGridView1.CurrentRow != null && dataGridView1.CurrentRow.Index > -1)
            {
                Process.AddCustomer(dataGridView1[0, dataGridView1.CurrentRow.Index].Value.ToString().Replace("pnd-", ""), CommonFun.removeTurkish(dataGridView1[1, dataGridView1.CurrentRow.Index].Value.ToString()));
            }
        }

        private void btnOtherDevice_Click(object sender, EventArgs e)
        {
            if (dataGridView1.CurrentRow != null && dataGridView1.CurrentRow.Index > -1)
            {
                string facedata = Process.getFaceData(dataGridView1[0, dataGridView1.CurrentRow.Index].Value.ToString().Replace("pnd-", ""));
                if (!string.IsNullOrEmpty(facedata) && facedata.IndexOf("face_data") > -1)
                {
                    Process.setFaceData(facedata);
                }
                else
                {
                    MessageBox.Show("Yüz tanıtma işlemi yapılmamış");
                }

            }
        }

        private void pictureBox2_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("http://www.bilisimbarkod.com");
        }


        private void LogToExcel()
        {
            try
            {
                string excel = Application.StartupPath + "\\log.xls";
                if (File.Exists(excel))
                {
                    File.Delete(excel);
                }

                using (System.IO.FileStream fs = new System.IO.FileStream(excel, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write))
                {
                    byte[] data = Properties.Resources.log;
                    fs.Write(data, 0, data.Length);
                    fs.Close();
                }

                if (File.Exists(Application.StartupPath + "\\log.txt"))
                {
                    string[] lines = File.ReadAllLines(Application.StartupPath + "\\log.txt");

                    using (OleDbConnection cn = new OleDbConnection(string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 8.0;HDR=YES\";", excel)))
                    {

                        cn.Open();
                        using (OleDbCommand cmd = new OleDbCommand("insert into [Log$] (Tarih,Saat,Kapi) values (@p1,@p2,@p3)", cn))
                        {
                            cmd.Parameters.Add("@p1", OleDbType.VarChar);
                            cmd.Parameters.Add("@p2", OleDbType.VarChar);
                            cmd.Parameters.Add("@p3", OleDbType.VarChar);

                            for (int i = 1; i < lines.Length; i++)
                            {
                                cmd.Parameters["@p1"].Value = lines[i].Split('\t')[0];
                                cmd.Parameters["@p2"].Value = lines[i].Split('\t')[1];
                                cmd.Parameters["@p3"].Value = lines[i].Split('\t')[2];
                                cmd.ExecuteNonQuery();
                            }
                        }
                        cn.Close();
                    }
                }

                if (File.Exists(excel))
                {
                    System.Diagnostics.Process.Start(excel);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void LogYaz()
        {
            if (!File.Exists(Application.StartupPath + "\\log.txt"))
            {
                using (StreamWriter sw = new StreamWriter(Application.StartupPath + "\\log.txt", false))
                {
                    sw.WriteLine("Kapı Açılış Tarihi\tKapı Açılış Saati\tKapı Adı");
                    sw.WriteLine(DateTime.Now.ToShortDateString() + "\t" + DateTime.Now.ToShortTimeString() + "\t" + cmbKapi.Text);
                    sw.Close();
                }
            }
            else
            {
                using (StreamWriter sw = new StreamWriter(Application.StartupPath + "\\log.txt", true))
                {
                    sw.WriteLine(DateTime.Now.ToShortDateString() + "\t" + DateTime.Now.ToShortTimeString() + "\t" + cmbKapi.Text);
                    sw.Close();
                }
            }
        }


        private void btnTurnikeAc_Click(object sender, EventArgs e)
        {
            if (cmbKapi.SelectedIndex > -1)
            {
                int no = Convert.ToInt32(cmbKapi.SelectedItem.ToString().Split('-')[0]);
                foreach (Cihaz item in Program.Db.Cihazlar)
                {
                    if (item.No == no)
                    {
                        openDoor(item.IpAdresi);
                        LogYaz();
                        break;
                    }
                }
            }
        }

        private void logGörüntüleToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LogToExcel();
        }

    }
}
